package com.luych.oauth2Server.controller;

import com.luych.common.constant.UserMessageConstant;
import com.luych.common.page.Page;
import com.luych.oauth2Server.controller.vo.Oauth2ClientVo;
import com.luych.oauth2Server.entity.Oauth2Client;
import com.luych.oauth2Server.service.Oauth2Service;
import org.apache.commons.beanutils.BeanUtils;
import org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.ResponseEntity;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.web.bind.annotation.*;

import java.lang.reflect.InvocationTargetException;
import java.util.ArrayList;
import java.util.List;
import java.util.UUID;

@RestController
public class Oauth2Controller {

    private final Logger logger = LoggerFactory.getLogger(this.getClass());

    private final Oauth2Service oauth2Service;
    private final PasswordEncoder passwordEncoder;

    @Autowired
    public Oauth2Controller(Oauth2Service oauth2Service, PasswordEncoder passwordEncoder) {
        this.oauth2Service = oauth2Service;
        this.passwordEncoder = passwordEncoder;
    }

    @GetMapping("oauth2/client")
    public ResponseEntity<Page> page(Page page, String keywords) throws InvocationTargetException, IllegalAccessException {
        page = oauth2Service.pageClient(keywords, page);
        List<Oauth2ClientVo> oauth2ClientVos = new ArrayList<>(page.getRecords().size());
        for (int i = 0; i < page.getRecords().size(); i++) {
            Oauth2Client oauth2Client = (Oauth2Client) page.getRecords().get(i);
            Oauth2ClientVo oauth2ClientVo = new Oauth2ClientVo();
            BeanUtils.copyProperties(oauth2ClientVo, oauth2Client);
            oauth2ClientVos.add(oauth2ClientVo);
        }
        page.setRecords(oauth2ClientVos);
        return new  ResponseEntity<>(page, HttpStatus.OK);
     }

    @PutMapping(value = "oauth2/client", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Oauth2Client> add(@RequestBody Oauth2Client oauth2Client) {
        if (StringUtils.isEmpty(oauth2Client.getClientId())) {
            oauth2Client.setClientId(UUID.randomUUID().toString().replace("-", ""));
        }
        if (StringUtils.isEmpty(oauth2Client.getClientSecret())) {
            oauth2Client.setClientSecret(UUID.randomUUID().toString().replace("-", ""));
        }
        oauth2Client.setClientSecret(passwordEncoder.encode(oauth2Client.getClientSecret()));
        return new ResponseEntity<>(oauth2Service.addClient(oauth2Client), HttpStatus.OK);
    }

    @PostMapping(value = "oauth2/client/{clientId}", consumes = MediaType.APPLICATION_JSON_VALUE)
    public ResponseEntity<Oauth2Client> modify(@PathVariable String clientId, @RequestBody Oauth2Client oauth2Client) {
        oauth2Client.setClientId(clientId);
        if (oauth2Client.getClientSecret() != null) {
            oauth2Client.setClientSecret(passwordEncoder.encode(oauth2Client.getClientSecret()));
        }
        return new ResponseEntity<>(oauth2Service.modifyClient(oauth2Client), HttpStatus.OK);
    }

    @DeleteMapping(value = "oauth2/client/{clientId}")
    public ResponseEntity<String> remove(@PathVariable String clientId) {
        oauth2Service.removeClient(clientId);
        return new ResponseEntity<>(clientId, HttpStatus.OK);
    }

    @GetMapping(value = "login")
    @ResponseStatus(code = HttpStatus.UNAUTHORIZED, reason = UserMessageConstant.error_NeedUserLogin)
    public void oauth2Login() {
        logger.info("oauth2Login");
    }


    @GetMapping(value = "oauth/error")
    @ResponseStatus(code = HttpStatus.FORBIDDEN)
    public String oauthError(Throwable throwable) {
        logger.info("oauthError");
        return throwable.getMessage();
    }

    @GetMapping(value = "/oauth/confirm_access")
    public String oauthConfirmAccess(String scope) {
        logger.info("oauthConfirmAccess");
        return scope;
    }

}
